import React from 'react';
import moment from 'moment';
import { Button, Icon, Modal, Card, Input, DatePicker, message, Select, Popconfirm } from 'antd';
import cass from 'classnames';
import s from './index.module.less';
import taskServer from '../../services/task';
import projectServer from '../../services/project';
import isSuccess from '../../utils/error';
import PickerModal from './PickerModal';
import NameTips from './NameTips';
import { observer, inject } from 'mobx-react';
const Option = Select.Option;

const { saveFile: saveProjectFile } = projectServer;
const { uploadFiles, saveFile: saveTaskFile } = taskServer;

export const fileIcon = {
  file: { icon: 'file-unknown', color: '#000' },
  audio: { icon: 'audio', color: '#3991f7' },
  word: { icon: 'file-word', color: '#315794' },
  excel: { icon: 'file-excel', color: '#56b888' },
  ppt: { icon: 'file-ppt', color: '#c45032' },
  pdf: { icon: 'file-pdf', color: '#ee6167' },
  text: { icon: 'file-text', color: '#1890ff' },
  image: { icon: 'picture', color: '#51bfe7' },
  zip: { icon: 'file-zip', color: '#f2b158' },
};

export function renderIcon(name) {
  if (/(png|jpeg|jpg|JPEG|JPG)/.test(name)) return fileIcon.image;
  else if (/txt/.test(name)) return fileIcon.text;
  else if (/pdf/.test(name)) return fileIcon.pdf;
  else if (/pptx|ppt/.test(name)) return fileIcon.ppt;
  else if (/xlsx|xls/.test(name)) return fileIcon.excel;
  else if (/(docx|doc)/.test(name)) return fileIcon.word;
  else if (/(mp3|mp4|m4a)/.test(name)) return fileIcon.audio;
  else if (/(rar|zip)/.test(name)) return fileIcon.zip;
  return fileIcon.file;
}

export function fileFormat(name) {
  const formatName = ['.png','.jpeg','.jpg','.JPEG','.JPG','.txt','.pdf','.pptx','.ppt','.xlsx','.xls','.docx','.doc','.mp3','.mp4','.m4a','.rar','.zip']
  const fileName = formatName.reduce((name, newName) => {
    return name.split(newName)[0]
  }, name)
  // const res =  name.match(/(.png|.jpeg|.jpg|.JPEG|.JPG|.txt|.pdf|.pptx|.ppt|.xlsx|.xls|.docx|.doc|.mp3|.mp4|.m4a|.rar|.zip)/)
  return fileName || name;
}

export function fileVerif(name) {
  const res = /(.png|.jpeg|.jpg|.JPEG|.JPG|.txt|.pdf|.pptx|.ppt|.xlsx|.xls|.docx|.doc|.mp3|.mp4|.m4a)/.test(name);
  return res;
}

const keyArr = ['dateValue', 'nameValue', 'signValue', 'stampValue', 'originValue', 'pageValue', 'partValue', 'remarkValue'];
export function getFileName(v, noExtension) {
  // 对象为无序集合，使用数组限定排序
  let str = '';
  const obj = {};
  keyArr.forEach((k) => {
    if (k === 'dateValue') {
      const date = v[k]?.split('-').join('') || '';
      str = str + (date ? date + '-' : '');
      obj.date = date;
    } else if (k === 'nameValue') {
      str = str + v[k];
      obj.name = v[k];
    } else if (k === 'signValue' && v[k]) {
      const sign = v[k] ? `-${v[k]}签字` : '-无签字';
      str = str + sign;
      obj.sign = v[k];
    } else if (k === 'stampValue' && v[k]) {
      const stamp = v[k] ? `-${v[k]}盖章` : '-无盖章';
      str = str + stamp;
      obj.mark = v[k];
    } else if (k === 'originValue') {
      const unit = v['pageValue'] || v['partValue'] || v['remarkValue'] ? '-原件-' : '-原件';
      str = str + v[k] + (v[k] ? unit : '');
      obj.original = v[k];
    } else if (k === 'pageValue' && v[k]) {
      const unit = v['partValue'] || v['remarkValue'] ? '-页-' : '-页';
      str = str + v[k] + (v[k] ? unit : '');
      obj.page = v[k];
    } else if (k === 'partValue' && v[k]) {
      const unit = v['remarkValue'] ? '-份-' : '-份';
      str = str + v[k] + (v[k] ? unit : '');
      obj.piece = v[k];
    } else if (k === 'remarkValue' && v[k]) {
      const remark = v[k] ? v[k] : '-无备注';
      str = str + remark;
      obj.remark = v[k];
    }
    console.log(k, v[k], str);
  });

  return {
    filename: noExtension ? str : str + `.${v.response.extension}`,
    sourcefilename: JSON.stringify(obj),
  };
}

@inject(({ projectState, taskState }) => ({ projectState, taskState }))
@observer
class UploadModal extends React.Component {
  static defaultProps = {
    needReflesh: 'false', // 用于项目模块添加自定义文件夹后刷新文件夹列表
    folderName: '', // 文件路径-- 文件夹名称
  };
  inputRefList = [];
  constructor(props) {
    super(props);
    this.state = {
      files: [],
      showEditOnly: true, // 只显示修改文件名输入框
      showModal: false,
      backupsData: null, // 备份数据
    };
  }
  componentDidMount() {
    if (this.props.showModalData) {
      const fileList = this.props.showModalData.files;
      const files = fileList
        .filter((file) => {
          const val = fileVerif(file.fileTarget.name);
          if (!val) {
            message.warning('部分文件的格式超出平台上传范围，已为您剔除');
          }
          return val;
        })
        .map((file) => {
          console.log(file);
          return { ...file, nameValue: fileFormat(file.fileTarget.name) };
        });

      this.setState({ files: files, showModal: true, backupsData: JSON.parse(JSON.stringify(fileList)), task: fileList[0]?.task });
    }
  }

  componentWillReceiveProps(next, prop) {
    if (next.show && !this.state.showModal) {
      !!this.FileTimer && clearTimeout(this.FileTimer);
      this.FileTimer = setTimeout(() => {
        this.selectFile(); // 弹窗显示先自动显示文件选择框
      }, 600);
    }
  }
  handleOk = async () => {
    const { files } = this.state;

    if (!files.length) {
      message.warning('请选择要上传的文件');
      return;
    }

    // if(files.length > 9) {
    //     message.warning('只可同时最多上传9份文档');
    //     return;
    // }

    this.setState({ confirmLoading: true });
    let canSave = true;
    const { showEditOnly } = this.state;
    if (!showEditOnly) {
      try {
        files.forEach((f, i) => {
          const { pathValue, dateValue, nameValue, originValue } = f;
          if (!pathValue) {
            throw new Error(`第${i + 1}个文件的保存路径不能为空`);
          }
          if (!dateValue) {
            throw new Error(`第${i + 1}个文件的文件落款/形成日期不能为空`);
          }
          if (!nameValue) {
            throw new Error(`第${i + 1}个文件的文件名不能为空`);
          }
          if (!originValue) {
            throw new Error(`第${i + 1}个文件是否为原件选项不能为空`);
          }
        });
      } catch (e) {
        // 避免遍历太多，使用try catch捕捉错误的方式结束foreach循环
        message.warn(e.message, 3);
        canSave = false;
      }
    }
    if (!canSave) {
      this.setState({ confirmLoading: false });
      return;
    }

    // 先上传文件
    const formData = new window.FormData();
    const filesData = files.map((f) => {
      f = {
        dateValue: '',
        nameValue: '',
        signValue: '',
        stampValue: '',
        originValue: '',
        pageValue: '',
        partValue: '',
        remarkValue: '',
        ...f,
      }; // 把父级文件夹填入
      formData.append('file', f.fileTarget, f.fileTarget.name);
      return f;
    });
    const res = await uploadFiles(formData);
    if (isSuccess(res)) {
      if (showEditOnly && !this.props?.showModalData) {
        const { type } = this.props;
        if (type === '1') {
          this.api_addfile(filesData, res);
        } else if (type === '2') {
          this.api_saveTaskFile(filesData, res);
        }
      } else if (this.props?.showModalData) {
        const { type:types } = this.props;
        const { project, stages, folder, type } = filesData[0];
        const data = filesData.map((item) => {
          return { ...item, project, stages, folder, type };
        });
        console.log('---uploadFiles---', res, type);
        this.handleSort(data, res,types);
      } else {
        this.handleSort(filesData, res);
      }
    } else {
      this.setState({ confirmLoading: false });
    }
  };
  /** 将上传好的文件放到对应项目下文件夹 */
  async api_addfile(files, res) {
    console.log('------------------------将上传好的文件放到对应项目下文件夹----------------------------');
    console.log(res);
    const { folderid, foldername, clientid, foldertype } = this.props.filesItem;
    const { detailData } = this.props.projectState;
    const params = {
      projectid: detailData.projectid,
      stageid: detailData.stages[0].stageid,
      files: [
        {
          folderid: folderid,
          foldername: foldername,
          clientid: clientid,
          foldertype: foldertype,
          items: files.map((item, i) => {
            const { filename, sourcefilename } = getFileName({ ...item, response: res[i] });
            return {
              filename,
              sourcefilename,
              folderid: folderid,
              uploadfileid: res[i].fileid,
              extension: res[i].extension,
            };
          }),
        },
      ],
    };
    try {
      const val = await saveProjectFile({ ...params });
      const { onUploadResult } = this.props;
      setTimeout(() => {
        onUploadResult(
          val,
          () => {
            message.success('上传成功！！！');
            this.onCancel();
            this.setState({ confirmLoading: false });
          },
          1000
        );
      });
    } catch (error) {
      message.warn('上传失败！', 3);
      this.onCancel();
      this.setState({ confirmLoading: false });
    }
  }
  // 上传到任务中
  async api_saveTaskFile(files, res) {
    const { detailData } = this.props.taskState;
    console.log('-------------------------detailData----------------------------');
    const params = {
      taskid: detailData.info.recid,
      files: files.map((item, i) => {
        const { filename, sourcefilename } = getFileName({ ...item, response: res[i] });
        return {
          filename,
          sourcefilename,
          uploadfileid: res[i].fileid,
        };
      }),
    };
    try {
      const val = await saveTaskFile({ ...params });
      const { onUploadResult } = this.props;
      setTimeout(() => {
        onUploadResult(
          val,
          () => {
            message.success('上传成功！！！');
            this.onCancel();
            this.setState({ confirmLoading: false });
          },
          1000
        );
      });
    } catch (error) {
      message.warn('上传失败！', 3);
      this.onCancel();
      this.setState({ confirmLoading: false });
    }
  }
  /**
   *  分类处理
   *  1. 不同类型：上传到文件夹和上传到任务
   *  2. 同样类型但是不同文件之间和不同任务之间
   * @param {*} files
   * @param {*} res
   */
  handleSort = async (files, res,types) => {
    const toProjectObj = {};
    const innerProjectObj = {};
    const toTaskObj = {};
    const { backupsData } = this.state;
    files.forEach((f, i) => {
      const { filename, sourcefilename } = getFileName({
        ...f,
        response: res[i],
      });
      console.log('-----------------------------f.folder.folderid---------------------------------');
      console.log(f);
      console.log(backupsData[0]);
      f = {
        ...f,
        stage: {
          ...backupsData[0].stage,
          ...f.stage,
        },
        folder: {
          ...backupsData[0].folder,
          ...f.folder,
        },
        project: {
          ...backupsData[0].project,
          ...f.project,
        },
        type: type ? type : backupsData[0].type,
      };
      console.log(f);
      const type = f.type;
      if (type === '1') {
        // 上传到文件夹
        // 已项目id为基准分类
        const key = f.project.recid;
        if (toProjectObj[key]) {
          const newFiles = toProjectObj[key].files;
          if (!newFiles.includes(f.folder.folderid)) {
            // 判断文件夹id是否重复
            newFiles.push(f.folder.folderid);
            toProjectObj[key].files = newFiles;
          }
        } else {
          toProjectObj[key] = {
            projectid: key,
            stageid: f.stage.stageid,
            files: [f.folder.folderid],
          };
        }

        // 已文件夹id为基准分类
        const innerKey = f.folder.folderid;
        if (innerProjectObj[innerKey]) {
          const newItems = innerProjectObj[innerKey].items;
          newItems.push({
            filename,
            sourcefilename,
            // filetype: 1,
            folderid: f.folder.folderid,
            uploadfileid: res[i].fileid,
            extension: res[i].extension,
          });
          innerProjectObj[innerKey].items = newItems;
        } else {
          innerProjectObj[innerKey] = {
            folderid: f.folder.folderid,
            foldername: f.folder.foldername,
            clientid: f.folder.clientid,
            foldertype: f.folder.foldertype,
            // innerfoldertype: f.folder.innerfoldertype,
            items: [
              {
                filename,
                sourcefilename,
                // filetype: 1,
                folderid: f.folder.folderid,
                uploadfileid: res[i].fileid,
                extension: res[i].extension,
              },
            ],
          };
        }
      } else if (type === '2') {
        // 上传到任务
        const { task } = this.state;
        console.log('-------------------------task------------------------------');
        console.log(task);
        const key = f.task?.recid || task?.recid;
        if(key) {
          if (toTaskObj[key]) {
            const newFiles = toTaskObj[key].files;
            newFiles.push({
              filename,
              sourcefilename,
              uploadfileid: res[i].fileid,
            });
            toTaskObj[key].files = newFiles;
          } else {
            toTaskObj[key] = {
              taskid: key,
              files: [
                {
                  filename,
                  sourcefilename,
                  uploadfileid: res[i].fileid,
                },
              ],
            };
          }
        }
      }
      if(types == '2') {
        const { detailData } = this.props.taskState;
        let key = detailData.info.recid;
        toTaskObj[key] = {
          taskid: key,
          files: [
            {
              filename,
              sourcefilename,
              uploadfileid: res[i].fileid,
            },
          ],
        };
      }
      
    });
    // console.log('===================oProjectObj, innerProjectObj======================');
    // console.log(toProjectObj, innerProjectObj);
    // 遍历对象为数组
    const uploadProjectData = [];
    for (let key in toProjectObj) {
      const files = toProjectObj[key].files.map((k) => innerProjectObj[k]);
      uploadProjectData.push(saveProjectFile({ ...toProjectObj[key], files }));
    }

    const uploadTaskData = [];
    for (let key in toTaskObj) {
      uploadTaskData.push(saveTaskFile(toTaskObj[key]));
    }

    const allRes = await Promise.all([...uploadProjectData, ...uploadTaskData]);

    const { onCancel, onUploadResult } = this.props;

    onUploadResult(allRes, () => {
      message.success('上传成功！！！');
      this.onCancel();
      this.setState({ confirmLoading: false });
    });
  };

  onMinus = (i) => () => {
    console.log('--------------------------------------------', i);
    const { files } = this.state;
    this.setState({
      files: [...files.slice(0, i), ...files.slice(i + 1)],
    });
    // 如果没有文件数据就通知关闭弹窗
    if (!files.length) {
      this.onCancel();
    }
  };

  onFileChage = (e) => {
    console.log('----------------------------e.target.files------------------------------------');
    console.log(e.target.files);
    const fileList = e.target.files;
    const { files } = this.state;
    const newFiles = files.concat();
    // 由于原生获取到的FileList数组没有map函数，所以要先用for循环遍历到一个新数组中
    for (let i = 0; i < fileList.length; i++) {
      const file = fileList[i];
      console.log('----------------------------files------------------------------------');
      console.log(files, file.name);
      const val = fileVerif(file.name);
      if (!val) {
        message.warning('部分文件的格式超出平台上传范围，已为您剔除');
        continue;
      }
      if (!files.some((f) => f.fileTarget.name === file.name)) {
        const data = {
          fileTarget: fileList[i],
          nameValue: fileFormat(fileList[i].name),
          signValue: '',
          stampValue: '',
          remarkValue: '',
        };
        newFiles.push(data);
      }
    }
    e.target.remove();
    this.setState({ files: newFiles, showModal: true });
  };

  selectFile = () => {
    if (this.input) {
      this.clearInput();
    }
    const input = document.createElement('input');
    input.type = 'file';
    input.multiple = true;
    input.style.display = 'none';
    input.addEventListener('change', this.onFileChage);
    document.body.appendChild(input);
    this.input = input;
    input.click();
  };
  clearInput() {
    if (this.input) {
      // 移除上传input相关
      this.input.remove();
      this.input.removeEventListener('change', this.onFileChage);
      this.input = undefined;
      this.setState({ showModal: false });
    }
  }
  onCancel = () => {
    this.clearInput();
    const { onCancel } = this.props;
    this.setState({ files: [] }, onCancel);
  };

  showPickerModal = (i) => {
    this.activeFileIndex = i;
    this.setState({ pickerShow: true });
  };

  hidePickerModal = () => {
    this.setState({ pickerShow: false });
  };

  onPathValueChange = (v, callback) => {
    const { files } = this.state;
    // 设置其它空文件路径默认值为当前选中值
    const newFiles = files.map((f, i) => {
      if (i === this.activeFileIndex || !f.pathValue) {
        return { ...f, ...v };
      }
      return f;
    });
    this.setState({ files: newFiles });
    callback && callback();
  };

  onValueChange = (key, i, onlyNum) => (v, time) => {
    console.log('------------------------------------------------------------------');
    const { files } = this.state;
    const newFiles = files.concat();
    if (key === 'nameValue' && !files.nameValue) {
      // eslint-disable-next-line no-unused-expressions
      this.inputRefList[i]?.input?.focus?.();
    }
    if (onlyNum === 'num') {
      const { value } = v.target;
      const reg = /^-?(0|[1-9][0-9]*)(\.[0-9]*)?$/;
      if (!((!Number.isNaN(value) && reg.test(value)) || value === '' || value === '-')) {
        return;
      }
    }

    let value = v;
    if (key === 'dateValue') value = time;
    else if (key === 'originValue') value = v;
    else value = v.target.value;
    const target = { ...files[i], [key]: value };
    newFiles[i] = target;
    this.setState({ files: newFiles });
  };
  /** 打开本地文件 */
  openFile = (item) => {
    console.log('---------------------打开本地文件-----------------------------');
    console.log(item);
    const { ipcRenderer } = window.electron;
    const msg = { path: item.path, name: item.name };
    ipcRenderer.send('openFile', JSON.stringify(msg));
  };
  goBack() {
    const { showModalData, goBack } = this.props;
    // this.onCancel();
    !!showModalData && !!goBack && goBack();
  }
  render() {
    const { show, needReflesh, projectid, projecttype, stageid, taskid, type, folderName, stagename, recname, showModalData, groupname, begintime } = this.props;
    const { files, confirmLoading, pickerShow, showEditOnly, showModal } = this.state;
    const pathValue = folderName + (stagename ? ` - [${stagename}]` : '') + (recname ? ` ${recname}` : '');
    return (
      <Modal
        title={
          <div style={{ height: '20px' }}>
            <div
              style={{ position: 'absolute', left: '10px', fontWeight: 'bold', fontSize: '16px', alignItems: 'center' }}
              className={cass(s.flexRow, s.btn)}
              onClick={() => this.goBack()}
            >
              {!!showModalData && <Icon type="left" style={{ marginTop: '2px', marginRight: '10px' }} />}
              <span>文件命名</span>
            </div>
          </div>
        }
        maskClosable={false}
        visible={show && showModal}
        width={680}
        onCancel={() => this.onCancel()}
        closable={false}
        footer={
          <div className={s.flexRowBetween}>
            <Button type="primary" onClick={this.selectFile}>
              + 添加文档
            </Button>
            <div>
              <Button key="cancle" onClick={this.onCancel}>
                取消
              </Button>
              <Button key="sure" type="primary" onClick={this.handleOk} loading={confirmLoading}>
                确定
              </Button>
            </div>
          </div>
        }
        wrapClassName={s.wrapModal}
      >
        <div className={s.content}>
          {folderName ? (
            <div className={cass(s.flexRowBetween, s.borderBottom, s.btn)} onClick={() => this.openFilePath()}>
              <h3>上传路径：{pathValue}</h3>
            </div>
          ) : (
            // <h3>{files.length ? `已选择${files.length}份文件` : '请选择要上传的文件'}</h3>
            null
          )}
          {groupname?<h3>任务名称：{begintime + '  ' + groupname}</h3>:null}
          <div className={s.wrap}>
            {files.map((file, i) => {
              const { icon, color } = renderIcon(file.fileTarget.name);
              return (
                <Card key={`file${i}`} hoverable bordered={false}>
                  <div className={s.header}>
                    <div className={s.flexRow}>
                      <Icon type={icon} className={s.icon} style={{ color }} />
                      <div className={s.fileName} onClick={() => this.openFile(file.fileTarget)}>
                        {i + 1}、{file.fileTarget.name}
                      </div>
                    </div>
                    <div onClick={this.onMinus(i)} className={s.clearBtn}>
                      <Icon type="minus-circle" className={s.minus} />
                    </div>
                  </div>
                  {showEditOnly ? (
                    // 新的上传只显示文件名修改给用户看，其他的不显示
                    <div className={s.inputBox}>
                      <Input
                        ref={(el) => (this.inputRefList[i] = el)}
                        allowClear
                        value={file.nameValue}
                        onChange={this.onValueChange('nameValue', i)}
                      />
                    </div>
                  ) : (
                    <>
                      <div className={s.title}>
                        <div />
                        保存路径 <span className={s.pathReq}>*</span>
                      </div>
                      <div className={s.wrapInput}>
                        <Input
                          onClick={() => this.showPickerModal(i)}
                          value={file.pathValue}
                          placeholder={'请选择上传的项目文件夹或任务'}
                          suffix={<Icon type="down" style={{ color: 'rgba(0,0,0,.25)' }} />}
                        />
                      </div>
                      <div className={s.title}>
                        <div />
                        文件名
                      </div>
                      <div className={s.wrapInput}>
                        <div className={cass(s.require, s.wrapdate)}>
                          <DatePicker
                            value={file.dateValue ? moment(file.dateValue) : null}
                            onChange={this.onValueChange('dateValue', i)}
                            className={s.date}
                            placeholder="文件落款/形成日期"
                          />
                        </div>
                        <div className={cass(s.require, s.name)}>
                          <Input value={file.nameValue} onChange={this.onValueChange('nameValue', i)} placeholder="文件名" />
                        </div>
                        <div className={cass(s.require, s.origin)}>
                          <Select
                            className={s.select}
                            value={file.originValue}
                            onChange={this.onValueChange('originValue', i)}
                            placeholder="原件"
                          >
                            <Option value="有">有原件</Option>
                            <Option value="无">无原件</Option>
                          </Select>
                        </div>
                      </div>
                      <div className={s.wrapInput1}>
                        <div className={s.item0}>
                          <Input value={file.signValue} onChange={this.onValueChange('signValue', i)} placeholder="签字人" />
                          <div className={s.text}>签字</div>
                        </div>
                        <div className={s.item0}>
                          <Input value={file.stampValue} onChange={this.onValueChange('stampValue', i)} placeholder="盖章人" />
                          <div className={s.text}>盖章</div>
                        </div>
                        <div className={cass(s.item0, s.item1)}>
                          <Input value={file.pageValue} onChange={this.onValueChange('pageValue', i, 'num')} placeholder="" />
                          <div className={cass(s.rqeText)}>页</div>
                        </div>
                        <div className={cass(s.item0, s.item1)}>
                          <Input value={file.partValue} onChange={this.onValueChange('partValue', i, 'num')} placeholder="" />
                          <div className={cass(s.rqeText)}>份</div>
                        </div>
                        <div className={cass(s.item0, s.item2)}>
                          <Input value={file.remarkValue} onChange={this.onValueChange('remarkValue', i)} placeholder="备注" />
                        </div>
                      </div>
                    </>
                  )}
                </Card>
              );
            })}
          </div>
          {show && !!files.length && <NameTips />}
          {!!pickerShow && (
            <PickerModal
              title="请选择保存路径"
              showfooter
              type={type}
              taskid={taskid}
              stageid={stageid}
              projectid={projectid}
              projecttype={projecttype}
              needReflesh={needReflesh}
              visible
              onOk={this.onPathValueChange}
              onCancel={this.hidePickerModal}
            />
          )}
        </div>
      </Modal>
    );
  }
}

export default UploadModal;
